/* 
 * $Id: JGraphEditorTool.java,v 1.2 2005/10/15 10:28:23 gaudenz Exp $
 * Copyright (c) 2001-2005, Gaudenz Alder
 * 
 * All rights reserved.
 * 
 * See LICENSE file for license details. If you are unable to locate
 * this file please contact info (at) jgraph (dot) com.
 */
package com.jgraph.editor;

import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;
import javax.swing.Action;

import org.jgraph.graph.BasicMarqueeHandler;

/**
 * The base class for all tools in a JGraph editor kit. Tools are used to
 * temporary set a graphs marquee handler, ie. to take over all interactions on
 * a graph. This is typically used to insert new cells in marquee-style (as
 * opposed to dnd-style used in the library).
 */
public class JGraphEditorTool extends BasicMarqueeHandler
        implements JGraphAction {

	private UpdateListener mUpdateListener;

	private Action mAction = new AbstractAction() {
		private static final long serialVersionUID = 1L;
		@Override
		public void actionPerformed(ActionEvent e) {
			/* do nothing */;
		}
	};

	/**
	 * Holds the name.
	 */
	protected String name;

	/**
	 * Specifies whether this tool is always activated. Default is false. A
	 * value of true means the tool will always be called by the toolbox
	 * redirector if the tool is selected.
	 */
	protected boolean isAlwaysActive = true;

	/**
	 * Constructs a tool with the specified name.
	 * 
	 * @param name
	 *            The name of the tool to be created.
	 */
	public JGraphEditorTool(String name) {
		this(name, true);
	}

	/**
	 * Constructs a tool with the specified name.
	 * 
	 * @param name
	 *            The name of the tool to be created.
	 */
	public JGraphEditorTool(String name, boolean isAlwaysActive) {
		setName(name);
		this.isAlwaysActive = isAlwaysActive;
	}

	/**
	 * Sets the name of the tool.
	 * 
	 * @param name
	 *            The name to set.
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Returns true if this tool is always active, eg if it should return true
	 * whenever {@link #isForceMarqueeEvent(MouseEvent)} is called.
	 * 
	 * @return Returns the isAlwaysActive.
	 */
	public boolean isAlwaysActive() {
		return isAlwaysActive;
	}

	/**
	 * Sets whether the tool is always active.
	 * 
	 * @param isAlwaysActive
	 *            The isAlwaysActive to set.
	 */
	public void setAlwaysActive(boolean isAlwaysActive) {
		this.isAlwaysActive = isAlwaysActive;
	}

	/**
	 * Returns the name of the tool.
	 * 
	 * @return Returns the name.
	 */
	public String getName() {
		return name;
	}

	@Override
	public boolean isEnabled() {
		return mAction.isEnabled();
	}

	@Override
	public void setEnabled(boolean enabled) {
		mAction.setEnabled(enabled);
	}

	@Override
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		mAction.addPropertyChangeListener(listener);
	}

	@Override
	public Object getValue(String key) {
		return mAction.getValue(key);
	}

	@Override
	public void putValue(String key, Object value) {
		mAction.putValue(key, value);
	}

	@Override
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		mAction.removePropertyChangeListener(listener);
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		mAction.actionPerformed(event);
	}

	@Override
	public boolean isSelected() {
		Boolean isSelected = (Boolean) getValue(PROPERTY_ISSELECTED);
		if (isSelected != null) {
			return isSelected.booleanValue();
		}
		return false;
	}

	@Override
	public boolean isToggleAction() {
		return true;
	}

	@Override
	public boolean isVisible() {
		Boolean isVisible = (Boolean) getValue(PROPERTY_ISVISIBLE);
		if (isVisible != null) {
			return isVisible;
		}
		return false;
	}

	@Override
	public void setSelected(boolean selected) {
		putValue(PROPERTY_ISSELECTED, selected);
	}

	@Override
	public void setToggleAction(boolean isToggleAction) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setVisible(boolean visible) {
		putValue(PROPERTY_ISVISIBLE, visible);		
	}

	/**
	 * Updates the tool state. The default implementation call the
	 * {@link UpdateListener} if such is registered.
	 */
	public void update() {
        if (mUpdateListener != null) {
        	mUpdateListener.onUpdate(this);
        }
	}

    /**
     * Gets the {@link UpdateListener} for this tool.
     *
     * @return The listener.
     */
	public UpdateListener getUpdateListener() {
		return mUpdateListener;
	}

	/**
     * Sets the {@link UpdateListener} for this tool.
     *
     * @param The listener.
     */
	public void setUpdateListener(UpdateListener updateListener) {
		mUpdateListener = updateListener;
	}

	/**
	 * Listener invoked when the tool is updated and more precisely
	 * when the {@link JGraphEditorTool#update()} is invoked.
	 */
	public static interface UpdateListener {
		/**
		 * Called when the tool is updated.
		 *
		 * @param tool The update tool.
		 */
		public void onUpdate(JGraphEditorTool tool);
	}
}